/**
 * Basic Email parser
 * By Lourens Elzinga
 */

package org.emailclassifier.extractdb;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;

/**
 * Email parser
 * 
 * Parses raw email files and splits the individual headers and the body.
 * Also has the option to save/load to/from JSON format.
 * 
 * @author Lourens Elzinga
 *
 */
public class EmailParser {
	
	private String m_body;
	private HashMap<String, String> m_headers;
	private String m_path;
	private String m_filename;
	
	/**
	 * Constructs a new Email Parser instance
	 */
	public EmailParser()
	{
		m_headers = new HashMap<String, String>();
		m_body = "";
		m_path = "";
		m_filename = "";
	}

	
	/**
	 * Parses the given email file
	 * @param file The file to parse
	 * @return True on success, false otherwise
	 */
	public boolean parseEmail(String file)
	{
		
		File fi = new File(file);
		m_path = fi.getAbsolutePath();
		m_filename = fi.getName();
		fi = null;
		
		m_headers.clear();
		
		FileReader f = null;
		
		try {
			f = new FileReader(file);
			BufferedReader io = new BufferedReader(f);
			
			// Parse headers
			String hName = null;
			String hValue = null;
			for(;;)
			{
				String header = io.readLine();
				if (header.trim().isEmpty()) {
					// End of headers
					
					if (hName != null)
						m_headers.put(hName.toLowerCase(), hValue);
					
					break;
				}
				
				int pos = header.indexOf(": ");
				if (pos == -1) {
					// Continuation of previous header
					hValue += header.trim();
				} else {
					if (hName != null)
						m_headers.put(hName.toLowerCase(), hValue);
					// New header
					hName = header.substring(0, pos);
					hValue = header.substring(pos + 2);
				}
			}
			
			// Parse body
			String newLine;
			String crlf = System.getProperty("line.separator");
			StringBuffer body = new StringBuffer();
			while ((newLine = io.readLine()) != null)
			{
				body.append(newLine);
				body.append(crlf);			
			}
			m_body = body.toString();
			f.close();
		} 
		catch (Exception e) {
			System.err.println("Error: " + e.getMessage() + " on file: " + file);
			m_headers.clear();
			return false;
		}
		return true;
	}
	
	/**
	 * Retrieves the specified header
	 * 
	 * @param header The header to retrieve (i.e. "To") (Not case-sensitive)
	 * @return The requested, or null if the header is not present
	 */
	public String getHeader(String header)
	{
		if (!m_headers.containsKey(header.toLowerCase()))
			return null;
		
		return m_headers.get(header.toLowerCase());
		
	}
	
	/**
	 * Returns the subject of the email
	 * @return The subject of the email
	 */
	public String getSubject()
	{
		return getHeader("subject");	
	}
	
	public String getRawMail()
	{
		StringBuilder sb = new StringBuilder();
		
		for (String key : m_headers.keySet())
		{
			sb.append(key);
			sb.append(": ");
			sb.append(m_headers.get(key));
			sb.append("\n");
		}
		
		sb.append("\n");
		sb.append(m_body);
		
		return sb.toString();
	}
	
	/**
	 * Returns the sender of the email
	 * @return The sender of the email
	 */
	public String getSender()
	{
		return getHeader("from");	
	}
	public String[] getRecipients()
	{
		String to = getHeader("to");
		if (to == null)
		{
			return new String[] { "" };
		} else if (to.indexOf(", ") != -1) {
			return to.split(", ");
		}
		
		return new String[] { to };
	}
	
	/**
	 * Returns the absolute path to the file parsed
	 * @return The absolute path to the file parsed
	 */
	public String getPath()
	{
		return m_path;
	}
	
	
	/**
	 * Returns the filename of the file parsed
	 * @return The filename of the file parsed
	 */
	public String getFileName()
	{
		return m_filename;
	}
	
	/**
	 * Retrieves the body of the email
	 * @return The body of the email
	 */
	public String getBody()
	{
		return m_body;
	}
	
}
